home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 6_2008-2009.ISO / data / zips / Advance_In2141451252009.psc / Inventory System / Classes / clsBlowfish.cls
Text File  |  2005-06-21  |  27KB  |  564 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "clsBlowfish"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15.  
  16. ' Visual Basic Blowfish Implementation
  17. ' Algorithm Author: Bruce Schneier
  18. ' VB Implementation: David Midkiff (mznull@earthlink.net)
  19. '
  20. ' Standard Blowfish implementation with file support, Base64 conversion,
  21. ' and overall optimisations for Visual Basic. Blowfish is considered one
  22. ' of the strongest encryption algorithms on the market and is much faster
  23. ' than the IDEA cipher. It supports variable length keys up to 448-bits. I
  24. ' would recommend this cipher for high security risk related solutions since
  25. ' it is unpatented and free for use.
  26. '
  27. ' Information on the Blowfish algorithm can be found at:
  28. ' http://www.counterpane.com/blowfish.html
  29.  
  30. Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
  31.  
  32. Event Progress(Percent As Long)
  33.  
  34. Private Const Rounds = 16
  35.  
  36. Private m_pBox(0 To Rounds + 1) As Long
  37. Private m_sBox(0 To 3, 0 To 255) As Long
  38. Private m_KeyValue As String
  39. Private m_RunningCompiled As Boolean
  40. Private m_bytIndex(0 To 63) As Byte
  41. Private m_bytReverseIndex(0 To 255) As Byte
  42.  
  43. Private Const k_bytEqualSign As Byte = 61
  44. Private Const k_bytMask1 As Byte = 3
  45. Private Const k_bytMask2 As Byte = 15
  46. Private Const k_bytMask3 As Byte = 63
  47. Private Const k_bytMask4 As Byte = 192
  48. Private Const k_bytMask5 As Byte = 240
  49. Private Const k_bytMask6 As Byte = 252
  50. Private Const k_bytShift2 As Byte = 4
  51. Private Const k_bytShift4 As Byte = 16
  52. Private Const k_bytShift6 As Byte = 64
  53. Private Const k_lMaxBytesPerLine As Long = 152
  54. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)
  55.  
  56. Private Sub Initialize64()
  57.     m_bytIndex(0) = 65 'Asc("A")
  58.     m_bytIndex(1) = 66 'Asc("B")
  59.     m_bytIndex(2) = 67 'Asc("C")
  60.     m_bytIndex(3) = 68 'Asc("D")
  61.     m_bytIndex(4) = 69 'Asc("E")
  62.     m_bytIndex(5) = 70 'Asc("F")
  63.     m_bytIndex(6) = 71 'Asc("G")
  64.     m_bytIndex(7) = 72 'Asc("H")
  65.     m_bytIndex(8) = 73 'Asc("I")
  66.     m_bytIndex(9) = 74 'Asc("J")
  67.     m_bytIndex(10) = 75 'Asc("K")
  68.     m_bytIndex(11) = 76 'Asc("L")
  69.     m_bytIndex(12) = 77 'Asc("M")
  70.     m_bytIndex(13) = 78 'Asc("N")
  71.     m_bytIndex(14) = 79 'Asc("O")
  72.     m_bytIndex(15) = 80 'Asc("P")
  73.     m_bytIndex(16) = 81 'Asc("Q")
  74.     m_bytIndex(17) = 82 'Asc("R")
  75.     m_bytIndex(18) = 83 'Asc("S")
  76.     m_bytIndex(19) = 84 'Asc("T")
  77.     m_bytIndex(20) = 85 'Asc("U")
  78.     m_bytIndex(21) = 86 'Asc("V")
  79.     m_bytIndex(22) = 87 'Asc("W")
  80.     m_bytIndex(23) = 88 'Asc("X")
  81.     m_bytIndex(24) = 89 'Asc("Y")
  82.     m_bytIndex(25) = 90 'Asc("Z")
  83.     m_bytIndex(26) = 97 'Asc("a")
  84.     m_bytIndex(27) = 98 'Asc("b")
  85.     m_bytIndex(28) = 99 'Asc("c")
  86.     m_bytIndex(29) = 100 'Asc("d")
  87.     m_bytIndex(30) = 101 'Asc("e")
  88.     m_bytIndex(31) = 102 'Asc("f")
  89.     m_bytIndex(32) = 103 'Asc("g")
  90.     m_bytIndex(33) = 104 'Asc("h")
  91.     m_bytIndex(34) = 105 'Asc("i")
  92.     m_bytIndex(35) = 106 'Asc("j")
  93.     m_bytIndex(36) = 107 'Asc("k")
  94.     m_bytIndex(37) = 108 'Asc("l")
  95.     m_bytIndex(38) = 109 'Asc("m")
  96.     m_bytIndex(39) = 110 'Asc("n")
  97.     m_bytIndex(40) = 111 'Asc("o")
  98.     m_bytIndex(41) = 112 'Asc("p")
  99.     m_bytIndex(42) = 113 'Asc("q")
  100.     m_bytIndex(43) = 114 'Asc("r")
  101.     m_bytIndex(44) = 115 'Asc("s")
  102.     m_bytIndex(45) = 116 'Asc("t")
  103.     m_bytIndex(46) = 117 'Asc("u")
  104.     m_bytIndex(47) = 118 'Asc("v")
  105.     m_bytIndex(48) = 119 'Asc("w")
  106.     m_bytIndex(49) = 120 'Asc("x")
  107.     m_bytIndex(50) = 121 'Asc("y")
  108.     m_bytIndex(51) = 122 'Asc("z")
  109.     m_bytIndex(52) = 48 'Asc("0")
  110.     m_bytIndex(53) = 49 'Asc("1")
  111.     m_bytIndex(54) = 50 'Asc("2")
  112.     m_bytIndex(55) = 51 'Asc("3")
  113.     m_bytIndex(56) = 52 'Asc("4")
  114.     m_bytIndex(57) = 53 'Asc("5")
  115.     m_bytIndex(58) = 54 'Asc("6")
  116.     m_bytIndex(59) = 55 'Asc("7")
  117.     m_bytIndex(60) = 56 'Asc("8")
  118.     m_bytIndex(61) = 57 'Asc("9")
  119.     m_bytIndex(62) = 43 'Asc("+")
  120.     m_bytIndex(63) = 47 'Asc("/")
  121.     m_bytReverseIndex(65) = 0 'Asc("A")
  122.     m_bytReverseIndex(66) = 1 'Asc("B")
  123.     m_bytReverseIndex(67) = 2 'Asc("C")
  124.     m_bytReverseIndex(68) = 3 'Asc("D")
  125.     m_bytReverseIndex(69) = 4 'Asc("E")
  126.     m_bytReverseIndex(70) = 5 'Asc("F")
  127.     m_bytReverseIndex(71) = 6 'Asc("G")
  128.     m_bytReverseIndex(72) = 7 'Asc("H")
  129.     m_bytReverseIndex(73) = 8 'Asc("I")
  130.     m_bytReverseIndex(74) = 9 'Asc("J")
  131.     m_bytReverseIndex(75) = 10 'Asc("K")
  132.     m_bytReverseIndex(76) = 11 'Asc("L")
  133.     m_bytReverseIndex(77) = 12 'Asc("M")
  134.     m_bytReverseIndex(78) = 13 'Asc("N")
  135.     m_bytReverseIndex(79) = 14 'Asc("O")
  136.     m_bytReverseIndex(80) = 15 'Asc("P")
  137.     m_bytReverseIndex(81) = 16 'Asc("Q")
  138.     m_bytReverseIndex(82) = 17 'Asc("R")
  139.     m_bytReverseIndex(83) = 18 'Asc("S")
  140.     m_bytReverseIndex(84) = 19 'Asc("T")
  141.     m_bytReverseIndex(85) = 20 'Asc("U")
  142.     m_bytReverseIndex(86) = 21 'Asc("V")
  143.     m_bytReverseIndex(87) = 22 'Asc("W")
  144.     m_bytReverseIndex(88) = 23 'Asc("X")
  145.     m_bytReverseIndex(89) = 24 'Asc("Y")
  146.     m_bytReverseIndex(90) = 25 'Asc("Z")
  147.     m_bytReverseIndex(97) = 26 'Asc("a")
  148.     m_bytReverseIndex(98) = 27 'Asc("b")
  149.     m_bytReverseIndex(99) = 28 'Asc("c")
  150.     m_bytReverseIndex(100) = 29 'Asc("d")
  151.     m_bytReverseIndex(101) = 30 'Asc("e")
  152.     m_bytReverseIndex(102) = 31 'Asc("f")
  153.     m_bytReverseIndex(103) = 32 'Asc("g")
  154.     m_bytReverseIndex(104) = 33 'Asc("h")
  155.     m_bytReverseIndex(105) = 34 'Asc("i")
  156.     m_bytReverseIndex(106) = 35 'Asc("j")
  157.     m_bytReverseIndex(107) = 36 'Asc("k")
  158.     m_bytReverseIndex(108) = 37 'Asc("l")
  159.     m_bytReverseIndex(109) = 38 'Asc("m")
  160.     m_bytReverseIndex(110) = 39 'Asc("n")
  161.     m_bytReverseIndex(111) = 40 'Asc("o")
  162.     m_bytReverseIndex(112) = 41 'Asc("p")
  163.     m_bytReverseIndex(113) = 42 'Asc("q")
  164.     m_bytReverseIndex(114) = 43 'Asc("r")
  165.     m_bytReverseIndex(115) = 44 'Asc("s")
  166.     m_bytReverseIndex(116) = 45 'Asc("t")
  167.     m_bytReverseIndex(117) = 46 'Asc("u")
  168.     m_bytReverseIndex(118) = 47 'Asc("v")
  169.     m_bytReverseIndex(119) = 48 'Asc("w")
  170.     m_bytReverseIndex(120) = 49 'Asc("x")
  171.     m_bytReverseIndex(121) = 50 'Asc("y")
  172.     m_bytReverseIndex(122) = 51 'Asc("z")
  173.     m_bytReverseIndex(48) = 52 'Asc("0")
  174.     m_bytReverseIndex(49) = 53 'Asc("1")
  175.     m_bytReverseIndex(50) = 54 'Asc("2")
  176.     m_bytReverseIndex(51) = 55 'Asc("3")
  177.     m_bytReverseIndex(52) = 56 'Asc("4")
  178.     m_bytReverseIndex(53) = 57 'Asc("5")
  179.     m_bytReverseIndex(54) = 58 'Asc("6")
  180.     m_bytReverseIndex(55) = 59 'Asc("7")
  181.     m_bytReverseIndex(56) = 60 'Asc("8")
  182.     m_bytReverseIndex(57) = 61 'Asc("9")
  183.     m_bytReverseIndex(43) = 62 'Asc("+")
  184.     m_bytReverseIndex(47) = 63 'Asc("/")
  185. End Sub
  186.  
  187. Public Function Decode64(sInput As String) As String
  188.     If sInput = "" Then Exit Function
  189.     Decode64 = StrConv(DecodeArray64(sInput), vbUnicode)
  190. End Function
  191.  
  192. Public Function DecodeArray64(sInput As String) As Byte()
  193.     If m_bytReverseIndex(47) <> 63 Then Initialize64
  194.     Dim bytInput() As Byte
  195.     Dim bytWorkspace() As Byte
  196.     Dim bytResult() As Byte
  197.     Dim lInputCounter As Long
  198.     Dim lWorkspaceCounter As Long
  199.     
  200.     bytInput = Replace(Replace(sInput, vbCrLf, ""), "=", "")
  201.     ReDim bytWorkspace(LBound(bytInput) To (UBound(bytInput) * 2)) As Byte
  202.     lWorkspaceCounter = LBound(bytWorkspace)
  203.     For lInputCounter = LBound(bytInput) To UBound(bytInput)
  204.         bytInput(lInputCounter) = m_bytReverseIndex(bytInput(lInputCounter))
  205.     Next lInputCounter
  206.     
  207.     For lInputCounter = LBound(bytInput) To (UBound(bytInput) - ((UBound(bytInput) Mod 8) + 8)) Step 8
  208.         bytWorkspace(lWorkspaceCounter) = (bytInput(lInputCounter) * k_bytShift2) + (bytInput(lInputCounter + 2) \ k_bytShift4)
  209.         bytWorkspace(lWorkspaceCounter + 1) = ((bytInput(lInputCounter + 2) And k_bytMask2) * k_bytShift4) + (bytInput(lInputCounter + 4) \ k_bytShift2)
  210.         bytWorkspace(lWorkspaceCounter + 2) = ((bytInput(lInputCounter + 4) And k_bytMask1) * k_bytShift6) + bytInput(lInputCounter + 6)
  211.         lWorkspaceCounter = lWorkspaceCounter + 3
  212.     Next lInputCounter
  213.     
  214.     Select Case (UBound(bytInput) Mod 8):
  215.         Case 3:
  216.             bytWorkspace(lWorkspaceCounter) = (bytInput(lInputCounter) * k_bytShift2) + (bytInput(lInputCounter + 2) \ k_bytShift4)
  217.         Case 5:
  218.             bytWorkspace(lWorkspaceCounter) = (bytInput(lInputCounter) * k_bytShift2) + (bytInput(lInputCounter + 2) \ k_bytShift4)
  219.             bytWorkspace(lWorkspaceCounter + 1) = ((bytInput(lInputCounter + 2) And k_bytMask2) * k_bytShift4) + (bytInput(lInputCounter + 4) \ k_bytShift2)
  220.             lWorkspaceCounter = lWorkspaceCounter + 1
  221.         Case 7:
  222.             bytWorkspace(lWorkspaceCounter) = (bytInput(lInputCounter) * k_bytShift2) + (bytInput(lInputCounter + 2) \ k_bytShift4)
  223.             bytWorkspace(lWorkspaceCounter + 1) = ((bytInput(lInputCounter + 2) And k_bytMask2) * k_bytShift4) + (bytInput(lInputCounter + 4) \ k_bytShift2)
  224.             bytWorkspace(lWorkspaceCounter + 2) = ((bytInput(lInputCounter + 4) And k_bytMask1) * k_bytShift6) + bytInput(lInputCounter + 6)
  225.             lWorkspaceCounter = lWorkspaceCounter + 2
  226.     End Select
  227.     
  228.     ReDim bytResult(LBound(bytWorkspace) To lWorkspaceCounter) As Byte
  229.     If LBound(bytWorkspace) = 0 Then lWorkspaceCounter = lWorkspaceCounter + 1
  230.     CopyMemory VarPtr(bytResult(LBound(bytResult))), VarPtr(bytWorkspace(LBound(bytWorkspace))), lWorkspaceCounter
  231.     DecodeArray64 = bytResult
  232. End Function
  233.  
  234. Public Function Encode64(ByRef sInput As String) As String
  235.     If sInput = "" Then Exit Function
  236.     Dim bytTemp() As Byte
  237.     bytTemp = StrConv(sInput, vbFromUnicode)
  238.     Encode64 = EncodeArray64(bytTemp)
  239. End Function
  240.  
  241. Public Function EncodeArray64(ByRef bytInput() As Byte) As String
  242.     On Error GoTo ErrorHandler
  243.     
  244.     If m_bytReverseIndex(47) <> 63 Then Initialize64
  245.     Dim bytWorkspace() As Byte, bytResult() As Byte
  246.     Dim bytCrLf(0 To 3) As Byte, lCounter As Long
  247.     Dim lWorkspaceCounter As Long, lLineCounter As Long
  248.     Dim lCompleteLines As Long, lBytesRemaining As Long
  249.     Dim lpWorkSpace As Long, lpResult As Long
  250.     Dim lpCrLf As Long
  251.  
  252.     If UBound(bytInput) < 1024 Then
  253.         ReDim bytWorkspace(LBound(bytInput) To (LBound(bytInput) + 4096)) As Byte
  254.     Else
  255.         ReDim bytWorkspace(LBound(bytInput) To (UBound(bytInput) * 4)) As Byte
  256.     End If
  257.  
  258.     lWorkspaceCounter = LBound(bytWorkspace)
  259.  
  260.     For lCounter = LBound(bytInput) To (UBound(bytInput) - ((UBound(bytInput) Mod 3) + 3)) Step 3
  261.         bytWorkspace(lWorkspaceCounter) = m_bytIndex((bytInput(lCounter) \ k_bytShift2))
  262.         bytWorkspace(lWorkspaceCounter + 2) = m_bytIndex(((bytInput(lCounter) And k_bytMask1) * k_bytShift4) + ((bytInput(lCounter + 1)) \ k_bytShift4))
  263.         bytWorkspace(lWorkspaceCounter + 4) = m_bytIndex(((bytInput(lCounter + 1) And k_bytMask2) * k_bytShift2) + (bytInput(lCounter + 2) \ k_bytShift6))
  264.         bytWorkspace(lWorkspaceCounter + 6) = m_bytIndex(bytInput(lCounter + 2) And k_bytMask3)
  265.         lWorkspaceCounter = lWorkspaceCounter + 8
  266.     Next lCounter
  267.  
  268.     Select Case (UBound(bytInput) Mod 3):
  269.         Case 0:
  270.             bytWorkspace(lWorkspaceCounter) = m_bytIndex((bytInput(lCounter) \ k_bytShift2))
  271.             bytWorkspace(lWorkspaceCounter + 2) = m_bytIndex((bytInput(lCounter) And k_bytMask1) * k_bytShift4)
  272.             bytWorkspace(lWorkspaceCounter + 4) = k_bytEqualSign
  273.             bytWorkspace(lWorkspaceCounter + 6) = k_bytEqualSign
  274.         Case 1:
  275.             bytWorkspace(lWorkspaceCounter) = m_bytIndex((bytInput(lCounter) \ k_bytShift2))
  276.             bytWorkspace(lWorkspaceCounter + 2) = m_bytIndex(((bytInput(lCounter) And k_bytMask1) * k_bytShift4) + ((bytInput(lCounter + 1)) \ k_bytShift4))
  277.             bytWorkspace(lWorkspaceCounter + 4) = m_bytIndex((bytInput(lCounter + 1) And k_bytMask2) * k_bytShift2)
  278.             bytWorkspace(lWorkspaceCounter + 6) = k_bytEqualSign
  279.         Case 2:
  280.             bytWorkspace(lWorkspaceCounter) = m_bytIndex((bytInput(lCounter) \ k_bytShift2))
  281.             bytWorkspace(lWorkspaceCounter + 2) = m_bytIndex(((bytInput(lCounter) And k_bytMask1) * k_bytShift4) + ((bytInput(lCounter + 1)) \ k_bytShift4))
  282.             bytWorkspace(lWorkspaceCounter + 4) = m_bytIndex(((bytInput(lCounter + 1) And k_bytMask2) * k_bytShift2) + ((bytInput(lCounter + 2)) \ k_bytShift6))
  283.             bytWorkspace(lWorkspaceCounter + 6) = m_bytIndex(bytInput(lCounter + 2) And k_bytMask3)
  284.     End Select
  285.  
  286.     lWorkspaceCounter = lWorkspaceCounter + 8
  287.  
  288.     If lWorkspaceCounter <= k_lMaxBytesPerLine Then
  289.         EncodeArray64 = Left$(bytWorkspace, InStr(1, bytWorkspace, Chr$(0)) - 1)
  290.     Else
  291.         bytCrLf(0) = 13
  292.         bytCrLf(1) = 0
  293.         bytCrLf(2) = 10
  294.         bytCrLf(3) = 0
  295.         ReDim bytResult(LBound(bytWorkspace) To UBound(bytWorkspace))
  296.         lpWorkSpace = VarPtr(bytWorkspace(LBound(bytWorkspace)))
  297.         lpResult = VarPtr(bytResult(LBound(bytResult)))
  298.         lpCrLf = VarPtr(bytCrLf(LBound(bytCrLf)))
  299.         lCompleteLines = Fix(lWorkspaceCounter / k_lMaxBytesPerLine)
  300.         
  301.         For lLineCounter = 0 To lCompleteLines
  302.             CopyMemory lpResult, lpWorkSpace, k_lMaxBytesPerLine
  303.             lpWorkSpace = lpWorkSpace + k_lMaxBytesPerLine
  304.             lpResult = lpResult + k_lMaxBytesPerLine
  305.             CopyMemory lpResult, lpCrLf, 4&
  306.             lpResult = lpResult + 4&
  307.         Next lLineCounter
  308.         
  309.         lBytesRemaining = lWorkspaceCounter - (lCompleteLines * k_lMaxBytesPerLine)
  310.         If lBytesRemaining > 0 Then CopyMemory lpResult, lpWorkSpace, lBytesRemaining
  311.         EncodeArray64 = Left$(bytResult, InStr(1, bytResult, Chr$(0)) - 1)
  312.     End If
  313.     Exit Function
  314.  
  315. ErrorHandler:
  316.     Erase bytResult
  317.     EncodeArray64 = bytResult
  318. End Function
  319.  
  320. Private Static Sub DecryptBlock(Xl As Long, Xr As Long)
  321.     Dim i As Long, j As Long, K As Long
  322.     K = Xr
  323.     Xr = Xl Xor m_pBox(Rounds + 1)
  324.     Xl = K Xor m_pBox(Rounds)
  325.     j = Rounds - 2
  326.     For i = 0 To (Rounds \ 2 - 1)
  327.         Xl = Xl Xor f(Xr)
  328.         Xr = Xr Xor m_pBox(j + 1)
  329.         Xr = Xr Xor f(Xl)
  330.         Xl = Xl Xor m_pBox(j)
  331.         j = j - 2
  332.     Next
  333. End Sub
  334. Private Static Sub EncryptBlock(Xl As Long, Xr As Long)
  335.     Dim i As Long, j As Long, Temp As Long
  336.     j = 0
  337.     For i = 0 To (Rounds \ 2 - 1)
  338.         Xl = Xl Xor m_pBox(j)
  339.         Xr = Xr Xor f(Xl)
  340.         Xr = Xr Xor m_pBox(j + 1)
  341.         Xl = Xl Xor f(Xr)
  342.         j = j + 2
  343.     Next
  344.     Temp = Xr
  345.     Xr = Xl Xor m_pBox(Rounds)
  346.     Xl = Temp Xor m_pBox(Rounds + 1)
  347. End Sub
  348. Public Sub EncryptByte(byteArray() As Byte, Optional Key As String)
  349.     Dim Offset As Long, OrigLen As Long, LeftWord As Long, RightWord As Long, CipherLen As Long, CipherLeft As Long, CipherRight As Long, CurrPercent As Long, NextPercent As Long
  350.     If (Len(Key) > 0) Then Me.Key = Key
  351.     OrigLen = UBound(byteArray) + 1
  352.     CipherLen = OrigLen + 12
  353.     If (CipherLen Mod 8 <> 0) Then CipherLen = CipherLen + 8 - (CipherLen Mod 8)
  354.     ReDim Preserve byteArray(CipherLen - 1)
  355.     Call CopyMem(byteArray(12), byteArray(0), OrigLen)
  356.     Call CopyMem(byteArray(8), OrigLen, 4)
  357.     Call Randomize
  358.     Call CopyMem(byteArray(0), CLng(2147483647 * Rnd), 4)
  359.     Call CopyMem(byteArray(4), CLng(2147483647 * Rnd), 4)
  360.     For Offset = 0 To (CipherLen - 1) Step 8
  361.         Call GetWord(LeftWord, byteArray(), Offset)
  362.         Call GetWord(RightWord, byteArray(), Offset + 4)
  363.         LeftWord = LeftWord Xor CipherLeft
  364.         RightWord = RightWord Xor CipherRight
  365.         Call EncryptBlock(LeftWord, RightWord)
  366.         Call PutWord(LeftWord, byteArray(), Offset)
  367.         Call PutWord(RightWord, byteArray(), Offset + 4)
  368.         CipherLeft = LeftWord
  369.         CipherRight = RightWord
  370.         If (Offset >= NextPercent) Then
  371.             CurrPercent = Int((Offset / CipherLen) * 100)
  372.             NextPercent = (CipherLen * ((CurrPercent + 1) / 100)) + 1
  373.             RaiseEvent Progress(CurrPercent)
  374.         End If
  375.     Next
  376.     If (CurrPercent <> 100) Then RaiseEvent Progress(100)
  377. End Sub
  378. Public Function EncryptString(Text As String, Optional Key As String, Optional OutputIn64 As Boolean) As String
  379.     Dim byteArray() As Byte
  380.     byteArray() = StrConv(Text, vbFromUnicode)
  381.     Call EncryptByte(byteArray(), Key)
  382.     EncryptString = StrConv(byteArray(), vbUnicode)
  383.     If OutputIn64 = True Then EncryptString = Encode64(EncryptString)
  384.     Erase byteArray(): Key = "": Text = ""
  385. End Function
  386. Public Function DecryptString(Text As String, Optional Key As String, Optional IsTextIn64 As Boolean) As String
  387.     Dim byteArray() As Byte
  388.     If IsTextIn64 = True Then Text = Decode64(Text)
  389.     byteArray() = StrConv(Text, vbFromUnicode)
  390.     Call DecryptByte(byteArray(), Key)
  391.     DecryptString = StrConv(byteArray(), vbUnicode)
  392.     Erase byteArray(): Key = "": Text = ""
  393. End Function
  394. Public Sub DecryptByte(byteArray() As Byte, Optional Key As String)
  395.     On Error GoTo ErrorHandler
  396.     Dim Offset As Long, OrigLen As Long, LeftWord As Long, RightWord As Long, CipherLen As Long, CipherLeft As Long, CipherRight As Long, CurrPercent As Long, NextPercent As Long
  397.     If (Len(Key) > 0) Then Me.Key = Key
  398.     CipherLen = UBound(byteArray) + 1
  399.     For Offset = 0 To (CipherLen - 1) Step 8
  400.         Call GetWord(LeftWord, byteArray(), Offset)
  401.         Call GetWord(RightWord, byteArray(), Offset + 4)
  402.         Call DecryptBlock(LeftWord, RightWord)
  403.         LeftWord = LeftWord Xor CipherLeft
  404.         RightWord = RightWord Xor CipherRight
  405.         Call GetWord(CipherLeft, byteArray(), Offset)
  406.         Call GetWord(CipherRight, byteArray(), Offset + 4)
  407.         Call PutWord(LeftWord, byteArray(), Offset)
  408.         Call PutWord(RightWord, byteArray(), Offset + 4)
  409.         If Offset >= NextPercent Then
  410.             CurrPercent = Int((Offset / CipherLen) * 100)
  411.             NextPercent = (CipherLen * ((CurrPercent + 1) / 100)) + 1
  412.             RaiseEvent Progress(CurrPercent)
  413.         End If
  414.     Next
  415.     Call CopyMem(OrigLen, byteArray(8), 4)
  416.     If (CipherLen - OrigLen > 19) Or (CipherLen - OrigLen < 12) Then Call Err.Raise(vbObjectError, , "Incorrect size descriptor in Blowfish decryption")
  417.     Call CopyMem(byteArray(0), byteArray(12), OrigLen)
  418.     ReDim Preserve byteArray(OrigLen - 1)
  419.     If CurrPercent <> 100 Then RaiseEvent Progress(100)
  420.  
  421. ErrorHandler:
  422. End Sub
  423. Private Static Function f(ByVal x As Long) As Long
  424.     Dim xb(0 To 3) As Byte
  425.     Call CopyMem(xb(0), x, 4)
  426.     If (m_RunningCompiled) Then f = (((m_sBox(0, xb(3)) + m_sBox(1, xb(2))) Xor m_sBox(2, xb(1))) + m_sBox(3, xb(0))) Else f = UnsignedAdd((UnsignedAdd(m_sBox(0, xb(3)), m_sBox(1, xb(2))) Xor m_sBox(2, xb(1))), m_sBox(3, xb(0)))
  427. End Function
  428. Private Static Sub GetWord(LongValue As Long, CryptBuffer() As Byte, Offset As Long)
  429.     Dim bb(0 To 3) As Byte
  430.     bb(3) = CryptBuffer(Offset)
  431.     bb(2) = CryptBuffer(Offset + 1)
  432.     bb(1) = CryptBuffer(Offset + 2)
  433.     bb(0) = CryptBuffer(Offset + 3)
  434.     Call CopyMem(LongValue, bb(0), 4)
  435. End Sub
  436. Private Static Sub PutWord(LongValue As Long, CryptBuffer() As Byte, Offset As Long)
  437.     Dim bb(0 To 3) As Byte
  438.     Call CopyMem(bb(0), LongValue, 4)
  439.     CryptBuffer(Offset) = bb(3)
  440.     CryptBuffer(Offset + 1) = bb(2)
  441.     CryptBuffer(Offset + 2) = bb(1)
  442.     CryptBuffer(Offset + 3) = bb(0)
  443. End Sub
  444. Private Static Function UnsignedAdd(ByVal Data1 As Long, Data2 As Long) As Long
  445.     Dim x1(0 To 3) As Byte, x2(0 To 3) As Byte, xx(0 To 3) As Byte, Rest As Long, Value As Long, a As Long
  446.     Call CopyMem(x1(0), Data1, 4)
  447.     Call CopyMem(x2(0), Data2, 4)
  448.     Rest = 0
  449.     For a = 0 To 3
  450.         Value = CLng(x1(a)) + CLng(x2(a)) + Rest
  451.         xx(a) = Value And 255
  452.         Rest = Value \ 256
  453.     Next
  454.     Call CopyMem(UnsignedAdd, xx(0), 4)
  455. End Function
  456. Private Function UnsignedDel(Data1 As Long, Data2 As Long) As Long
  457.     Dim x1(0 To 3) As Byte, x2(0 To 3) As Byte, xx(0 To 3) As Byte, Rest As Long, Value As Long, a As Long
  458.     Call CopyMem(x1(0), Data1, 4)
  459.     Call CopyMem(x2(0), Data2, 4)
  460.     Call CopyMem(xx(0), UnsignedDel, 4)
  461.     For a = 0 To 3
  462.         Value = CLng(x1(a)) - CLng(x2(a)) - Rest
  463.         If (Value < 0) Then
  464.             Value = Value + 256
  465.             Rest = 1
  466.         Else
  467.             Rest = 0
  468.         End If
  469.         xx(a) = Value
  470.     Next
  471.     Call CopyMem(UnsignedDel, xx(0), 4)
  472. End Function
  473. Public Property Let Key(New_Value As String)
  474.     Dim i As Long, j As Long, K As Long, dataX As Long, datal As Long, datar As Long, Key() As Byte, KeyLength As Long
  475.     Class_Initialize
  476.     If (m_KeyValue = New_Value) Then Exit Property
  477.     m_KeyValue = New_Value
  478.     KeyLength = Len(New_Value)
  479.     Key() = StrConv(New_Value, vbFromUnicode)
  480.     j = 0
  481.     For i = 0 To (Rounds + 1)
  482.         dataX = 0
  483.         For K = 0 To 3
  484.             Call CopyMem(ByVal VarPtr(dataX) + 1, dataX, 3)
  485.             dataX = (dataX Or Key(j))
  486.             j = j + 1
  487.             If (j >= KeyLength) Then j = 0
  488.         Next
  489.         m_pBox(i) = m_pBox(i) Xor dataX
  490.     Next
  491.     
  492.     datal = 0: datar = 0
  493.     For i = 0 To (Rounds + 1) Step 2
  494.         Call EncryptBlock(datal, datar)
  495.         m_pBox(i) = datal
  496.         m_pBox(i + 1) = datar
  497.     Next
  498.     For i = 0 To 3
  499.         For j = 0 To 255 Step 2
  500.             Call EncryptBlock(datal, datar)
  501.             m_sBox(i, j) = datal
  502.             m_sBox(i, j + 1) = datar
  503.         Next
  504.     Next
  505. End Property
  506. Private Sub Class_Initialize()
  507. On Local Error Resume Next
  508.   m_RunningCompiled = ((2147483647 + 1) < 0)
  509.   m_pBox(0) = &H243F6A88
  510.   m_pBox(1) = &H85A308D3
  511.   m_pBox(2) = &H13198A2E
  512.   m_pBox(3) = &H3707344
  513.   m_pBox(4) = &HA4093822
  514.   m_pBox(5) = &H299F31D0
  515.   m_pBox(6) = &H82EFA98
  516.   m_pBox(7) = &HEC4E6C89
  517.   m_pBox(8) = &H4579Fa3B   Call CopyMem(x1(0), Data12294eaEAAnitialize(2oxsox(3) = &H3707ea = (6bspactReverseIndex(87aoxsox(3t6 Local Er&H13198A2E
  518. b = (6bspactReverse_Value As String)
  519.     Dim i As Long, j As Long, K As LonSpac6        ng,-29D4C6C
  520.     Dim iPutWord(RigIAe8aBox(6) = b CopyMe70), U7bspactReabund7 'AscxhyC=5F24knd7 'As = b CopyMetializa, U7bspactReaUue = VaC75ex(55) = 51 'Asc("3")
  521.     mGF  pac6        ng,-29D4C6C
  522.     Dim iPutWo= (6bspactEeverse_Valueea7he And 25epjatar Aix(6) = b CopyMe70), U7b4tepnd 25epjatar Aix(6) = b Cgee a"te7b4tepnd 25epjatar Aix(6)7A58eDCtep b CopyMetializa, U7bspF5A288tedAs Stringtializa, U7b88DAteps Long, Temp As Long
  523.  akd 25etepAteps Long, Temp As LongB6F2l3hsN 25etepAteps Long, Temp As LoniE(t)
  524.         End If
  525.     Next
  526.     Call CopyMe CopyMetiasN 25etepAteps .e49tlp CopyMe CopyMetiasN 25ete7sN 25etepAt0taxld8nsigne9237EtepAteps Long, Temp As Lon8EE4A3tepAs LonSpa4 'Asc("Y3hsN 25elppE(t)
  527.     pa4 1eue Then Text = Decode64(Text)
  528.     byen Text =96544 1eue Th= Decode64(Text)
  529.   epAteps Long, Temp55C,n3sELverseIndex(84G Schn2epAteps .c Temp55C,n3sELverseIndex(P Long, Temp As LoniE(t)
  530.      pLoniE(t)
  531.      pLoniE(t(t)
  532. Long
  533.  )
  534.      pLoniE(t)
  535.      pLoniE(t(t)
  536. Long
  537.  )
  538.      pLoniE(t)
  539.      pLoniE(t(t)
  540. Long
  541.  )
  542.      pLoniE(t)
  543.   McTh= Decode64cl((bytmp A  pLoniE(t)
  544.   ((bytmp A  pLoAs Boolean)Etep,n3sELverseIndex(P Long, oniE(t)
  545.   McTp As LoneteIndex(P Long, oniE(t)
  546.   kmA8ascTp As e s4r
  547.  )
  548.     6
  549.             Rest = Ea e0ut5A288tedAs ep           Rest = Ea e0utBp As LoniE(t)
  550.          Restnl
  551.       aionalestnl
  552.   n0F/3n) Asg45 Boolean)Etep,n Ea e0atar Aix(6)7A58eDCtep b CopyMet85A308D3
  553.   m_pBr
  554.     Next
  555.     Call CopaD6Fs68ascTp As e s4r0atar Aix(6)75atar Aixujlest = E Next
  556.     CalteIndex(P Long, oniE(      Rest = Ea e0utC238e, vbFrCFC2sEa e0utC238e, vbFrCFC2sEa e777CC768DteponiE(      Rest = Ea e0utA89BsIf (m_-Metializa, U7bspaDDse     Rest = Ea e0utA89BsIe=57E8B7tn0u/3n) Asg45 Booleb7rs4 e0u@/3n) Asg45 Booleb7rs4 e0u@/355C5EDtl0u    Rest = Ea e0.Key = KeyspaD6Fs68asDonale8D9B7sbytCrL Rest = Ea e0lestKey = Keysp uyspaD6F2pn55C5EDtl0u    Re88eD Rest = Ea e0en Exit 8DteponiE(      Ibn3Ascob  6
  557.             r3sbytCrL Rest = Ea e0lestKey = Keysp uyspaD6F2pn55C5EDtl2n + 8kpstKey =IE40  Rest = Ea e0uthe And 25epjatar Aix(6)d 25epjatar <25epjatar 8Ear25epjatk)rs m_sBox(2, xb(1))), m_sBox(sC)))ea, oniest 3))), m_sBoOm_sBox(2, xb( 3r <25epjata )), E-ea, oniest 3))), m_<25epjata )r Aix(6)d 25epjatara.Key = Kl01n3As(1))), m_sBox(sC)))ea, oniest 3))), m_sBoOm_sBox(2oolean StrC688e, vbFrCst = Ean3sELverseIndex( 7t25etepAt0taxldvbFrCFC2 = EanAest = EaO14Xl01n3As(1))a49e855se 45epjatar Aix(6)d0utBp A>bse 4Om_sBox(2, xb( 3r <25 ByBn5iO, xb( 3r <25 Bd(0u 3uxb( 3r <,uninitiali2 = KOx(2, xb( 3r 5 )), E-re 4= EanAest = EaO1 r3sbytEes
  558.     r 5 )n0B6p4= s
  559.     r 5(Donale8D9B7sbytCrbytM43t =bytM43tsbi5turbytM43t32B4B22sy = K) T2DDFEs0B6p4et85A308D3
  560. t2lApDDKOxl 4niE(      Ibn3Asx(P Let85A3 d@ea 25epjatar <25epjeDs2lar <25epjeDs2lar <25epjeDs2lar <25epjeDs2lar <25epjeipGjeDs2larr72DDFEs0mRa5BBgB6p4et85A308D3
  561. t2lApDDKOxl 4niE(      Ibn3Asx(P   Ibn3Asx(P 7KCt=y c0svAe585Br7epjatareLEs0mRAsx(P4 Brpsl"7Ca7e4se0uength) Long,e4sagth) Long,e4saga"e27gBrpsl"7Ch"e2aa1SEE7s7ga"e27gOlu    Res18 "7Ch"e2aa*60aliza, U0 n5s18 "7Cong,e4sagth) 4 T2DDFcCs78D9B7sbth) 4 T2DDFcCd5TD6Fs68ascTp nIbn3AsxrbytM43t32B4B22sy = K)rbj(40Ct32B4B22sy =Long, 355C5EDtl0u    Rest3cnO6 uyspaD6F2pn55C5EDs\w╡     N`m5=bytM43ÄÇax n5s18 "7Cong,e4sagth) 4 T2DDFcCs78D9=ar Aix(─₧{Ch"e2aa*60aliza, U0 n5s18 "7Cong,e4sagth) 4 T2DDìr}Cd5TD6Fs68ascTp nIbn3AsxrbytM43t32B4B22sy = K)rbj(40Ct32B4B22sy =Long, 355C5EDtl0u    Rest3cnO6 uyspaD6F2pn55C5EDs\w╡     N`m5=bytM436àä111 'Asc("o")
  562.     m_bytIndex(41) = 112 'Asc("p")
  563.     m_bytIndex(42) = 113 'Asc("q")
  564.     m_bytIndeS~z█,&<å}z25epjeDs2lar <25epjeDs2lar <25epjeipGjeFeDs2lar <25epjeDs2lar <25epjeDs2lar <25epjeDs2lar <25epjeipGjeDs2larr72DDFEs0mRa5BBgp]ô¢s,█¢"E8sbth) 4 T2DDFcCd5TD6Fs68ascTp nIbn3AsxrbytM43t32B4B22sy = K)¢8)àetepAt0taxld8nsigne9237ë╧*~D╜|=<25epjeDs2lar <25epjeipGjeFeDs2lar <25epjeDs2lar <25epjeDs2lar <25epjeDs2lar <25epjeipGjeDs2larr72DDFEs0mRa5BBgp~=C2 = EanAest alteIndex(P Long, oniE(      Rest = Ea e0utC238e, vbFrCFC2sEa e0utC238e, vbFrCFC2sEa e777CC768DteponiE(      Rest = Ea e0utA89BsIf (m_-Metializa, U7bspaDDse     Rest = Ea e0utA89BsIe=57E8B7tn0u/3n)